#pragma once
#include "db_common.h"
#include "logger.h"

class CatalogManager
{
public:
    CatalogManager();
    ~CatalogManager() = default;

    // 供SQL编译器调用的接口：查询表元数据
    json getCatalogInfo(const std::string &table_name);

    // 供执行引擎调用：创建新表的元数据
    bool createTable(const std::string &table_name, const std::vector<ColumnSchema> &cols, const std::string comment, uint32_t first_page_id = 0);

    // 供执行引擎调用：查询表的第一个数据页ID
    uint32_t getFirstPrimaryPageId(const std::string &table_name);

    TableSchema getTableSchema(const std::string &table_name);

    void updateTablePrimaryPageId(const std::string &table_name, uint32_t page_id);
    const std::unordered_map<std::string, TableSchema> &getAllSchemas() const
    {
        return table_map_;
    }
    void updateTablePageId(const std::string &table_name, uint32_t page_id);
    bool tableExists(const std::string &table_name);

    bool uniqueConstraintExists(const std::string &table_name, const std::string &col_name, const Value &val);

    bool createUniqueConstraint(const std::string &table_name, const std::string &col_name, const Value &val);

    bool indexExists(const std::string &table_name, const std::string &index_name);

    bool createIndex(const std::string &table_name, const std::string &index_name, const std::vector<std::string> &col_names, uint32_t root_page_id = 0, bool is_unique = false);

    bool dropIndex(const std::string &table_name, const std::string &index_name);

    IndexSchema getIndexSchema(const std::string &table_name, const std::string &index_name) const;
    void updateIndexRootPageId(const std::string &table_name, const std::string &index_name, uint32_t root_page_id);

    void dropTable(const std::string &table_name);

    IndexSchema getIndexSchemaByColumn(const std::string &table_name, const std::string &col_name) const;

    bool renameTable(const std::string &old_name, const std::string &new_name);

    bool modifyComment(const std::string &table_name, const std::string &comment);

    bool addColumns(const std::string &table_name, const std::vector<ColumnSchema> &cols);
    bool dropColumns(const std::string &table_name, const std::vector<std::string> &col_names);

    bool modifyColumns(const std::string &table_name, std::unordered_map<std::string, ModifiedColumn> &col_map,
                       std::unordered_map<std::string, int> need_to_auto_increment,
                       std::unordered_map<std::string, std::set<Value>> need_to_unique,
                       std::vector<std::string> need_to_drop_auto_increment,
                       std::vector<std::string> need_to_drop_unique);

    bool renameIndex(const std::string &table_name, const std::string &old_name, const std::string &new_name);

    bool addAutoIncrement(const std::string &table_name, const std::string &col_name, int start_value);

    bool dropAutoIncrement(const std::string &table_name, const std::string &col_name);

    bool addUniqueConstraint(const std::string &table_name, const std::string &col_name, std::set<Value> &values);

    bool dropUniqueConstraint(const std::string &table_name, const std::string &col_name);

    int64_t getAutoIncrementCounter(const std::string &table_name, const std::string &col_name);

    void setAutoIncrementCounter(const std::string &table_name, const std::string &col_name, int64_t counter);

    void deleteUniqueConstraint(const std::string &table_name, const std::string &col_name,const Value &val);

    void deleteUniqueConstraint(const std::string &table_name, const std::string &col_name);
private:
    // 从catalog.json加载元数据到内存
    void loadFromDisk();
    // 将内存元数据持久化到catalog.json
    void saveToDisk();

private:
    std::unordered_map<std::string, TableSchema> table_map_; // 表名→表结构
    Logger &logger_;                                         // 日志实例
};